package com.efuture.androidmvpdemo.net

import com.efuture.androidmvpdemo.net.ApiFactory.Holder.TAG
import com.efuture.netrequestdemo.utils.AppGlobal
import com.efuture.netrequestdemo.utils.LogUtil
import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import okhttp3.*
import okio.Buffer
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit
import org.json.JSONObject

/**

 *@description:接口请求工厂
 * @author: zhaoshanshan
 * @date: 2022/3/24 5:16 下午

 */

class ApiFactory {
    // 日志拦截器
    private val mLoggingInterceptor: Interceptor by lazy { LoggingInterceptor() }
    private val mClient:OkHttpClient by lazy { newClient()}
    private object Holder {  // 单例
        val INSTANCE = ApiFactory()
        const val  TAG = "NetRequest"
    }
    companion object { // 派生
        var instance = Holder.INSTANCE

    }

     fun<T>create(baseUrl:String, clazz: Class<T>):T{
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(mClient)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(CoroutineCallAdapterFactory())
            .build()
            .create(clazz)

    }

    private fun newClient():OkHttpClient = OkHttpClient.Builder().apply {
        connectTimeout(30, TimeUnit.SECONDS)// 连接时间：30s超时
        readTimeout(10, TimeUnit.SECONDS)// 读取时间：10s超时
        writeTimeout(10, TimeUnit.SECONDS)// 写入时间：10s超时
        if (AppGlobal.isDebugMode) addInterceptor(mLoggingInterceptor)// 仅debug模式启用日志过
    }.build()



    private class LoggingInterceptor:Interceptor{
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request()
            val response: Response = with(request) {
                LogUtil.v(TAG,"请求地址:$url")
                if(method=="POST"){
                    LogUtil.v(TAG,"请求参数:${printParams(request.body)}")
                }
                val response = chain.proceed(request)
                val mediaType = response.body!!.contentType();
                val content:String= response!!.body!!.string();
                LogUtil.v(TAG,"返回结果:$content}")
                return response.newBuilder()
                    .body(ResponseBody.create(mediaType, content))
                    .build();

            }
        }
        private fun printParams(body: RequestBody?):String{
            val buffer = Buffer()
            try {
                body!!.writeTo(buffer)
                var charset = Charset.forName("UTF-8")
                val contentType = body.contentType()
                if (contentType != null) {
                    charset = contentType.charset(charset)
                }
                var requestStr =  buffer.readString(charset!!)
                val split:List<String> = requestStr.split("&")
                val map = hashMapOf<String,Any>();
                split.forEach {
                    val data = it.split("=")
                    map[data[0]] = data[1]
                }
                requestStr = JSONObject(map as Map<*, *>).toString()
                return requestStr

            } catch (e: java.io.IOException) {
                e.printStackTrace()
                return "";
            }
        }

    }
}